package com.warrior.superdata.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.warrior.superdata.base.CommonResponse;
import com.warrior.superdata.constants.CommonConstant;
import com.warrior.superdata.constants.ResultCode;
import com.warrior.superdata.handler.ExportHandler;
import com.warrior.superdata.cache.ApiInfoCacheMap;
import com.warrior.superdata.exceptionhandler.ApplicationException;
import com.warrior.superdata.mysql.entity.dto.ApiInfoDetailDto;
import com.warrior.superdata.mysql.entity.dto.ApiParamDto;
import com.warrior.superdata.service.impl.SqlServiceImpl;
import com.warrior.superdata.util.JsonUtil;
import com.warrior.superdata.util.RequestUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiSort;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @Description:
 * @ClassName: com.warrior.wisdom.machine.room.controller.RequestHandlerController.java
 * @date: 2022/2/22 17:01
 * @author xujian
 */
@Api(tags = "扩展Api")
@ApiSort(4)
@Slf4j
@Controller
public class RequestHandlerController {

    private final static String PAGE = "page";

    private final static String SIZE = "size";

    @Autowired
    private SqlServiceImpl sqlService;

    @Autowired
    private ExportHandler exportHandler;

    @ResponseBody
    public Object invoke(HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
        String method = request.getMethod();
        String requestURI = request.getRequestURI();
        log.info("{}请求,uri:{}", method, requestURI);
        ApiInfoDetailDto apiInfoDetailDto = ApiInfoCacheMap.API_INFO_MAP.get(method + ":" + requestURI);
        if (null == apiInfoDetailDto) {
            throw new ApplicationException(ResultCode.FAIL_CODE, "未找到" + method + "请求的" + requestURI + "接口");
        }

        //如果是分页设置分页值
        if (CommonConstant.API_DATA_RESULT_PAGE == apiInfoDetailDto.getResultType()) {
            String page = request.getParameter(PAGE);
            String size = request.getParameter(SIZE);
            if (StringUtils.isEmpty(page) || Integer.valueOf(page) <= 0) {
                apiInfoDetailDto.setPage(1);
            } else {
                apiInfoDetailDto.setPage(Integer.valueOf(page));
            }
            if (StringUtils.isEmpty(size) || Integer.valueOf(size) <= 0) {
                apiInfoDetailDto.setSize(10);
            } else {
                apiInfoDetailDto.setSize(Integer.valueOf(size));
            }
        }
        Object bodyParam = RequestUtil.getBodyParam(request);
        List<ApiParamDto> params = apiInfoDetailDto.getParams();
        //以下逻辑会删除前端没有传参的元素，新增一个集合保存原请求参数
        List<ApiParamDto> newParams = new ArrayList<>();
        if (!CollectionUtils.isEmpty(params)) {
            Iterator<ApiParamDto> iterator = params.iterator();
            while (iterator.hasNext()) {
                ApiParamDto param = iterator.next();
                newParams.add(param);
                Integer paramBodyType = param.getParamBodyType();
                //url参数赋值
                if (CommonConstant.API_PARAM_URL == paramBodyType) {
                    String parameterValue = request.getParameter(param.getParamName());
                    if (StringUtils.isEmpty(parameterValue)) {
                        iterator.remove();
                    } else {
                        param.setParamValue(parameterValue);
                    }
                }
                //请求体参数赋值
                if (CommonConstant.API_PARAM_BODY == paramBodyType) {
                    if(null == bodyParam){
                        iterator.remove();
                    }
                    if (bodyParam instanceof JSONObject) {
                        String parameterValue = JsonUtil.getString(param.getParamName(), (JSONObject) bodyParam);
                        if (StringUtils.isEmpty(parameterValue)) {
                            iterator.remove();
                        } else {
                            param.setParamValue(parameterValue);
                        }
                    }

                    if (bodyParam instanceof JSONArray) {
                        List<String> values = new ArrayList<>();
                        ((JSONArray) bodyParam).forEach(item -> {
                            String parameterValue = JsonUtil.getString(param.getParamName(), (JSONObject) item);
                            parameterValue = StringUtils.isEmpty(parameterValue) ? CommonConstant.NULL_STRING : parameterValue;
                            values.add(parameterValue);
                        });

                        if (CollectionUtils.isEmpty(values)) {
                            iterator.remove();
                        } else {
                            param.setParamValue(StringUtils.join(values, CommonConstant.FIELD_VALUE_SPLICE_LIST));
                        }
                    }
                }
            }

        }

        Object execute = sqlService.execute(apiInfoDetailDto);

        apiInfoDetailDto.setParams(newParams);

        if (CommonConstant.EXPORT_API == apiInfoDetailDto.getIsExport()) {
            exportHandler.export(response, apiInfoDetailDto, execute);
            return null;
        }

        return CommonResponse.success(execute);
    }


}
